package com.augurit.common.system.web.auth;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;

import com.augurit.common.base.action.ProjBaseAction;
import com.augurit.common.base.form.ResultForm;
import com.augurit.common.constant.OrgConstant;
import com.augurit.common.syslog.service.ISysLoginLogService;
import com.augurit.common.syslog.web.form.SysLoginLogForm;
import com.augurit.common.system.entity.LoginConfine;
import com.augurit.common.system.service.auth.ILoginUserService;
import com.augurit.common.system.service.org.IAcMenuService;
import com.augurit.common.system.service.org.IAcRoleService;
import com.augurit.common.system.util.MsgUtils;
import com.augurit.common.system.util.OrgUtils;
import com.augurit.common.system.util.WebContextUtils;
import com.augurit.common.system.web.auth.form.LoginUserForm;
import com.augurit.common.system.web.org.form.OmOrgForm;
import com.augurit.common.util.Md5Utils;
import com.augurit.gzcgwsp.commonex.system.service.org.IOmOrgServiceEX;
import com.augurit.gzcgwsp.smartformCsdlwj.common.SmartDao;

/**
 * 用户登录Action类
 */
@SuppressWarnings("serial")
@Results({
	@Result(name = LoginAction.INDEX, location = "/index/index.action", type="redirect"),
	@Result(name = LoginAction.INIT_CONFIG, location = "/config/init-config.action", type="redirect"),
	@Result(name = LoginAction.LOGIN, location = "/common/system/auth/login.jsp")
})
public class LoginAction extends ProjBaseAction {
	
	public static final String LOGIN = "login";				//登录页面
	public static final String INDEX = "index";				//系统首页
	public static final String INIT_CONFIG = "init_config";	//初始化配置页面

	
	// Service 引用
	@Autowired
	private ILoginUserService loginUserService;
	
	@Autowired
	private IAcRoleService acRoleService;
	
	@Autowired
	private IAcMenuService acMenuService;
	
	@Autowired
	private ISysLoginLogService sysLoginLogService;
	
	@Autowired
    private IOmOrgServiceEX omOrgServiceEX;
	@Autowired
	private SmartDao smartDao;

	
	// 属性
	private String loginName;
	private String password;
	private String msg;
	
	private String closeWin = OrgConstant.ZERO;

	/**
	 * 打开用户登录页面或初始化配置页面
	 */
	public String login() throws Exception {
		if(WebContextUtils.isSystemInit(this.getApplication())){
			return LOGIN;
		}else{
			return INIT_CONFIG;
		}
	}
	
	
	/**
	 * 记录用户的登录信息
	 * @param userName 用户名，如果用户没有输入，用户名为anonymous
	 * @param success true,登录成功，反之则相反
	 * @param msg 登录信息
	 */
	private void recordLoginInfo(String userName, boolean success, String msg){
		SysLoginLogForm form = new SysLoginLogForm();
		form.setClientIp(this.getRequest().getRemoteAddr());
		form.setLoginTime(new Date());
		form.setUserName(userName);
		form.setLoginState(success?"Y":"N");
		form.setLoginMessage(msg);
		try {
			sysLoginLogService.save(form);
			Cookie c = new Cookie("loginName",loginName);//cookie记录用户名称
			c.setPath("/");   
			c.setMaxAge(3600000);
			getResponse().addCookie(c);
		} catch (Exception e) {
			
		}
		
	}
	
	/**
	 * 用户登录校验
	 */
	public String checkValid() throws Exception {
		String publicPassword = password;
		String pwd=Md5Utils.makeMd5Sum(password.getBytes());
//		password = org.hsqldb.lib.MD5.encodeString(password, "UTF-8");
		String numStr=this.getLoginConfine(loginName);
		if("false".equals(numStr)){
			 msg="登录超过8次，请15分钟后登录";
			recordLoginInfo(loginName, false, msg);
			return LOGIN;
		}
		// 获取登录用户信息
		ResultForm<LoginUserForm> result = loginUserService.getLoginUserInfo(loginName, pwd);
		if(result.isSuccess()){
			LoginUserForm loginUser = result.getResult();
			// 加载当前登录用户所拥有的功能ID集合
			boolean hasFuncs = initLoginUserFuncs(loginUser);
			if(!hasFuncs){
				msg = MsgUtils.MSG_NO_HAS_NO_FUNCS;
				return LOGIN;
			}
			// 存放登录用户信息
			this.setUserSession(loginUser);
			// 城管委添加----- begin -----------------------
            // 加载用户部门信息
            initLoginUserParentOrg(loginUser);
            // 城管委添加----- end -----------------------
			// 加载当前登录用户所拥有的角色ID集合
			initLoginUserRoles(loginUser);
			// 加载当前登录用户所拥有的菜单ID集合
			initLoginUserMenus(loginUser);
			//加载组织机构用户菜单
			initOrg(loginUser);
			
			this.savePublicPassword(publicPassword, loginUser.getUser().getUserId());
			//记录用户登录信息
			recordLoginInfo(loginUser.getUser().getUserName(), true, "");
			//清除以前登录错误信息
			loginUserService.saveErrorInfo(loginName,false);
			return INDEX;
		}else{
			msg = result.getErrMsg();
			loginUserService.saveErrorInfo(loginName,true);
			LoginConfine confine=loginUserService.getErrorInfo(loginName);
			msg="密码错误，还有"+(8-confine.getErrorNum())+"次登录";
			
			loginName = (loginName == null || loginName.trim().length() == 0?"anonymous":loginName);
			this.getLoginConfine(loginName);
			//记录用户登录信息
			recordLoginInfo(loginName, false, msg);
			return LOGIN;
		}
	}

	/**
	 * 加载组织机构
	 * @param loginUser
	 */
	private void initOrg(LoginUserForm loginUser) {
		 OmOrgForm orgForm = omOrgServiceEX.getUserOrg(loginUser.getUser().getUserId());
		 Long parentId=orgForm.getParentOrgId();
		 if(parentId!=null){
			 OmOrgForm parentOrg=this.omOrgServiceEX.getOrg(parentId);
		     loginUser.setParentOrg(parentOrg);
		    
		 }
	     loginUser.setOrg(orgForm);
	  
		
	}


	/**
	 * 记录登录错误信息
	 * @param username
	 * @return
	 */
	private   String getLoginConfine(String username) {
        String result="true";
        try {
            //查询错误登录记录表中有无此用户登录错误信息
        	LoginConfine confine = loginUserService.getErrorInfo(username);
            if (confine != null) {
            	int num=confine.getErrorNum();
                /*
                 * 计算时间差
                 */
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date d1 = new Date();
                Date d2 =confine.getLogintime()==null?new Date():confine.getLogintime();
                long diff = d1.getTime() - d2.getTime();
                long days = diff / (1000 * 60  * 15);
                if (confine.getErrorNum() < 5) {
                    if (days >= 1) {
                    	result="true";
                    } else if (days < 1) {
                    	result="true";
                    }
                 } else if (confine.getErrorNum() >= 5) {
                    if (days >= 1) {
                    	confine.setErrorNum(0);
                    	confine.setLogintime(new Date());
                    	loginUserService.saveErrorInfo(confine);
                    	result="true";
                    } else if (days < 1) {
                    	result="false";
                    }
                }
            } else {
            	result="true";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  result;
    }

	
	/**
	 * Action函数,默认action函数，默认指向list函数.
	 */
	public String execute() throws Exception {
		return login();
	}
	
	/**
	 * 重新登录
	 * @return
	 * @throws Exception
	 */
	public String logout() throws Exception {
		this.getSession().removeAttribute(WebContextUtils.SES_LOGIN_USER);
//		this.msg = OrgConstant.MSG_RELOGIN;
		return LOGIN;
	}
	
	/**
	 * 加载当前登录用户所拥有的角色ID集合
	 * @param loginUser
	 */
	private void initLoginUserRoles(LoginUserForm loginUser){
		Long[] roleIds = acRoleService.getAllRoleIdsByUserId(loginUser.getUser().getUserId());
		loginUser.setRoleIds(roleIds);
	}
	
	/**
	 * 加载当前登录用户所拥有的功能ID集合
	 * @param loginUser
	 * @return false表示用户不能访问任何功能，true表示用户存在可访问的功能
	 */
	private boolean initLoginUserFuncs(LoginUserForm loginUser){
		Long[] funcIds = acRoleService.getFuncIdsByUserId(loginUser.getUser().getUserId());
		
		if(funcIds != null && funcIds.length > 0){
			loginUser.setFuncIds(funcIds);
			this.getSession().setAttribute(WebContextUtils.SES_LOGIN_USER_FUNC, OrgUtils.convertToString(funcIds, ","));
			return true;
		}else
			return false;
	}
	
	/**
	 * 加载当前登录用户所拥有的菜单ID集合
	 * @param loginUser
	 */
	private void initLoginUserMenus(LoginUserForm loginUser){
		Long[] menuIds = acMenuService.getAllRelatedMenuIds(loginUser.getFuncIds());
		loginUser.setMenuIds(menuIds);
	}
	
	
	// 属性getter和setter方法
	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public String getCloseWin() {
		return closeWin;
	}

	public void setCloseWin(String closeWin) {
		this.closeWin = closeWin;
	}
	
	/**
     * 加载当前登录用户所拥有的角色ID集合
     * @param loginUser
     */
    private void initLoginUserParentOrg(LoginUserForm loginUser){
        OmOrgForm orgForm = omOrgServiceEX.getTopParentOrgOfUser(loginUser.getUser().getUserId());
        loginUser.setTopOrg(orgForm);
    }
    /**
     * 保存明文密码
     * @param password
     * @param userId
     */
    public void savePublicPassword(String password,Long userId){
    	String sql = "update OM_USER t set t.public_password='"+password+"' where t.user_id='"+userId+"'";
    	smartDao.executeSql(sql);
    }
}
